/*
 * Copyright (c) 2011 Junichiro Okuno
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those of the
 * authors and should not be interpreted as representing official policies, either expressed
 * or implied, of Junichiro Okuno.
 */

package tcp_net.management.user_account;

import tcp_net.TextInputOutput;
import tcp_net.management.FileManager;
import tcp_net.management.user_account.debug.DebugInfo;
import java.util.Random;
import java.util.Date;

import java.util.List;
import java.util.ArrayList;

/**
	This class provides to store email messages and related data
	@author J. Okuno
*/
public class Message
{
	/**
		Debug information
	*/
	private final static boolean DEBUG = DebugInfo.MESSAGE;
	
	/**
		A text input and output
	*/
	private final static TextInputOutput tio = new TextInputOutput();
	
	/**
		A file manager
	*/
	private FileManager f_manager;
	
	/**
		An email message size
	*/
	private int msg_size;
	
	/**
		A user name
	*/
	private String user_name;
	
	/**
		An email message text
	*/
	private String msg_text;
	
	/**
		A unique id
	*/
	private String unique_id;
	
	/**
		A message path
	*/
	private String msg_path;
	
	/**
		true if a message is delete marked
	*/
	private boolean deleted;
	
	/**
		Init Message (New message)
		@param u_name a user name
		@param m_text an email message
	*/
	public Message(String u_name, String m_text) 
	{ 
		f_manager = new FileManager();
		unique_id = null;
		
		user_name = u_name;
		msg_text = m_text;
		msg_path = "";
		
		msg_size = msg_text.length() * 8;
		deleted = false;
		
		saveMessageText();
		
		DebugInfo.print(DEBUG,"Message created");
	}
	
	/**
		Init Message (Restored message)
		@param u_name a user name
		@param uid a unique id
		@param m_path an email message path
		@param dlt true if a message is deletemarked
	*/
	public Message(String u_name, String uid, String m_path, boolean dlt)
	{
		f_manager = new FileManager();
		unique_id = uid;
		
		user_name = u_name;
		msg_path = m_path;
		msg_text = getMessageText();
		
		msg_size = msg_text.length() * 8;
		deleted = dlt;
		
		DebugInfo.print(DEBUG,"Message restored");
	}
	
	/**
		This method provides an email message file path
		@return an email message file path
	*/
	public String getMessagePath() { return msg_path; }
	
	/**
		This method provides a user name
		@return a user name
	*/
	public String getUserName() { return user_name; }
	
	/**
		This method saves an email message to a secondary storage
		@return true if an email message is saved
	*/
	private boolean saveMessageText()
	{
		createUserDataFolder();
		createUserFolder();
		createMessageFolder();
		
		tio.setText("./user_data/"+user_name+"/messages/"+getUniqueId()+".txt", msg_text);
		return true;
	}
	
	/**
		This method loads a saved message text from a secondary storage
		@return a saved message text from a secondary storage
	*/
	private String getMessageText()
	{
		if(msg_text==null) { msg_text = tio.getText("./user_data/"+user_name+"/messages/"+getUniqueId()+".txt"); }
		return msg_text;
	}
	
	/**
		This method provides a unique id of an email message
		@return a unique id of an email message
	*/
	public String getUniqueId() 
	{ 
		if(unique_id!=null) 
		{ 
			DebugInfo.print(DEBUG,"Unique Id requested: "+unique_id);
			return unique_id; 
		}
		
		else { return unique_id = generateUniqueId(); }
	}
	
	/**
		This method provides a size of an email message
		@return a size of an email message
	*/
	public int getMsgSize() { return msg_size; }
	
	/**	
		This method provides an email message text
		@return an email message text
	*/
	public String getMsgText() { return msg_text; }
	
	/**
		This method sets a message to be delete marked
		@param d true a message is to be delete marked
	*/
	public void setDeleted(boolean d) { deleted = d; }
	
	/**
		This method tests if a message is delete marked
		@return true if a message is delete marked
	*/
	public boolean isDeleted() { return deleted; }
	
	/**
		This method provides a line of an email message
		@param line_num a number of lines to be returned from the begining
		@return a list of email text lines  
	*/
	public List<String> getMsgText(int line_num) 
	{
		String lines[] = msg_text.split("\n");
		List line_list = new ArrayList<String>();
		
		for(int i=0; i < lines.length; i++)
		{
			line_list.add(lines[i]);
			if(i==line_num) { break; }
		}
		
		return line_list;
	}
	
	/**
		This method generates a unique ID for an email
		@return a unique ID for an email
	*/
	private String generateUniqueId()
	{
		DebugInfo.print(DEBUG,"New unique id is generated");
		int num1 = (new Random()).nextInt(999) + 1;
		long num2 = (new Date()).getTime();
		int num3 = (new Random()).nextInt(999) + 1;
		
		String id = num1+"."+num2+"."+num3;
		
		DebugInfo.print(DEBUG,"Id generated: "+id);
		return id;
	}
	
	
	//Folder creation
	
	/**
		This method creates a "user_data" folder
	*/
	private void createUserDataFolder() { f_manager.createDir(".", "user_data"); }
	
	/**
		This method creates a user name folder
	*/
	private void createUserFolder() { f_manager.createDir("./user_data", user_name);  }
	
	/**
		This method creates a "messages" folder
	*/
	private void createMessageFolder() { f_manager.createDir("./user_data/"+user_name, "messages");  }
}